#include "bridge.h"
#include <QDebug>
#include <QFile>
#include <QImage>
#include <QTextCodec>

IBridge* getBridge()
{
	IBridge* p_bridge = new Bridge();
	return p_bridge;
}

Bridge::Bridge()
{
	_path="adb/adb.exe"; 
	_command.clear();
	_selectedDevice.clear();  
}

Bridge::~Bridge()
{
	killServer();
}

//read output data
void Bridge::readOutput()
{
	_data.clear();
	_error.clear();
	// Continue reading the data until EOF reached
	while(_process.waitForReadyRead())
	{
		_data.append(_process.readAllStandardOutput());
		_error.append(_process.readAllStandardError());
	}
}

void Bridge::readScreenOutput()
{
	image.clear();
	// Continue reading the data until EOF reached
	while(_process.waitForReadyRead())
	{
		image.append(_process.readAllStandardOutput());
	}

	qDebug()<<"Size 1: "<<image.length();
	image.replace("\r\r\n", "\n");
	qDebug()<<"Size 2: "<<image.length();
}

//start adb server
void Bridge::startServer()
{
	killServer();
	_command=_path+" start-server";
    _process.start(_command);
	readOutput();
}
	
//kill adb server
void Bridge::killServer()
{
	_command=_path+" kill-server";
    _process.start(_command);
	readOutput();
}

//return list of unparsed strings with adb-name and model of device
QString Bridge::getDevices()
{
	_command=_path+" devices";
	_process.start(_command);
	readOutput();
	//qDebug() << _data;
	return _data;
}

QString Bridge::getDevicesProps(QString device)
{
	_command = _path + " -s " + device + " shell getprop";
	_process.start(_command);
	readOutput();	
	return _data;
}

//method sets name of the selected device at the moment
void Bridge::setSelectedDevice(QString s)
{
	_selectedDevice=s;
}

//save screenshot to path
bool Bridge::getScreenshot(QString str)
{
	bool result=false;
	qDebug() << "filepath: "<<str;
	if (!_selectedDevice.isEmpty())
	{
		_command=_path+" -s "+_selectedDevice+" shell screencap -p";
		_process.start(_command);
		readScreenOutput();

		QFile outFile(str);
		if (!outFile.open(QIODevice::WriteOnly))
		{
			qDebug() << "Error opening a file\n";
		}
		else
		{
			outFile.write(image);
			outFile.close();
			result=true;
		}
	}
	return result;
}

//return file system
QString Bridge::getFileSystem(QString s)
{
	_command=_path+" -s "+_selectedDevice+" shell ls -la \""+s+"\"";
	_process.start(formatToUTF8(_command));

	readOutput();
	return _data;
}


//method to create new Folder
bool Bridge::newFolder(QString name, QString path)
{
	_command = _path + " -s " + _selectedDevice + " shell mkdir \"" + path + name +"\"";
	_process.start(formatToUTF8(_command));

	readOutput();
	qDebug()<<"new_folder"<<_data;
	qDebug() <<"error:"<< _error;
	return _data.isEmpty()? true:false;
}

//method to remove selected item(folder,file)
bool Bridge::Delete(QString path, QString name)
{
	_command = _path + " -s " + _selectedDevice + " shell rm -r -f \"" + path + name +"\"";
	_process.start(formatToUTF8(_command));
	readOutput();

	qDebug()<<"delete_folder"<<_data;
	return _data.isEmpty()? true:false;
}

//method which provide installing .apk file from selected directory(PC or device)
bool Bridge::Install(QString cmd)
{
	_command = _path + " -s " + _selectedDevice + cmd ;
	_process.start(formatToUTF8(_command));
	readOutput();
	qDebug() <<"install"<< _data;
	return _data.isEmpty()? false:true;
}

//copy file to device
bool Bridge::pushToDevice(QString filePath,QString devicePath)
{
	int index = filePath.lastIndexOf("/")+1;
	QString name = filePath.right(filePath.length()-index);
	qDebug()<<"name:"<<name;
	QStringList arguments;
	arguments<<"-s"<<_selectedDevice<<"push";
	arguments.append(filePath);
	QString temp = devicePath + name;
	arguments.append(formatToUTF8(temp));
	qDebug()<<arguments;
	
	_process.start(_path,arguments);
	readOutput();
	
	qDebug() <<"error:"<< _error;
	bool res = _error.contains("bytes in");
	return res;
}

//copy file from device
bool Bridge::pullFromDevice(QString filePathOnDevice,QString pullPath)
{
	pullPath.replace("/","\\");
	int index = filePathOnDevice.lastIndexOf("/")+1;
	QString name = filePathOnDevice.right(filePathOnDevice.length()-index);
	qDebug()<<"name:"<<name;

	QStringList arguments;
	arguments<<"-s"<<_selectedDevice<<"pull";
	arguments.append(formatToUTF8(filePathOnDevice));

	qDebug()<<pullPath;
	QString temp;
	if (pullPath.endsWith("\\")) 
		temp = pullPath + name;
	else
		temp = pullPath + "\\" + name;
	qDebug()<<temp;
	arguments.append(temp);
	qDebug()<<arguments;

	_process.start(_path,arguments);
	readOutput();
	
	qDebug() <<"error:"<< _error;
	bool res = _error.contains("bytes in");
	return res;	
}

//check if a file exists with the same name
bool Bridge::checkName(QString, QString)
{
	return 0;
}

//paste: file or folder path, destination path, bool - copy(true) or cut(false) operation
// if cut - i will delete file or folder after copying
bool Bridge::Paste(QString,QString,bool)
{
	return 0;
}

bool Bridge::makeBackup(QString str)
{
	_command = _path + " -s " + _selectedDevice + " backup " + str;
	_process.start(formatToUTF8(_command));
	
	readOutput();
	qDebug() <<"backup"<< _data;
	return _data.isEmpty()? false:true;
}

bool Bridge::restoreBackup(QString file)
{
	_command = _path + " -s " + _selectedDevice + " restore \"" + file + "\"";
	_process.start(formatToUTF8(_command));

	readOutput();
	qDebug() <<"restore"<< _data;
	return _data.isEmpty()? false:true;
}

//This method providing to use UTF8 codec
QString Bridge::formatToUTF8(QString src)
{
	QTextCodec *codec = QTextCodec::codecForName("CP1251");
	QString final = codec->toUnicode(src.toUtf8());
	return final;
}

